package com.zjgsu.nftplatform.service.impl;

import com.zjgsu.nftplatform.service.IpfsService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author ahy231
 * @date 2022/3/9 15:03
 * @description
 */
@Service
public class IpfsServiceImpl implements IpfsService {

    private final RestTemplate restTemplate;

    @Value("${filepath.ipfs}")
    private String ipfsPath;

    @Value("${myurl.go-server}")
    private String server;

    @Value("${go-server.secret}")
    private String secret;

    public IpfsServiceImpl(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    public String cat(String hash) {
        byte[] bytes = restTemplate.getForObject("http://" + server + ":8068/cat?cid={hash}&secret={secret}", byte[].class, hash, secret);
        Assert.notNull(bytes, "Failed to get file from ipfs server.");
        return new String(bytes, Charset.defaultCharset()).replace("\0", "");
    }

    @Override
    public String get(String hash) {
        byte[] bytes = restTemplate.getForObject("http://" + server + ":8068/get?hash={hash}&outdir={outDir}&secret={secret}", byte[].class, hash, ipfsPath, secret);
        Assert.notNull(bytes, "Failed to get file from ipfs server.");
        return new String(bytes);
    }

    @Override
    public String add(MultipartFile file) {
        MultiValueMap<String, ByteArrayResource> map = new LinkedMultiValueMap<>();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, ByteArrayResource>> entity = new HttpEntity<>(map, headers);
        try {
            ByteArrayResource resource = new ByteArrayResource(file.getBytes()) {
                @Override
                public String getFilename() {
                    return file.getOriginalFilename();
                }
            };
            map.add(file.getName(), resource);
            map.add("secret", new ByteArrayResource(secret.getBytes(StandardCharsets.UTF_8)));
            byte[] bytes = restTemplate.postForObject("http://" + server + ":8068/add", entity, byte[].class);
            Assert.notNull(bytes, "Failed to add file to ipfs server");
            return new String(bytes, Charset.defaultCharset()).replace("\0", "");
        } catch (IOException e) {
            throw new RuntimeException("Cannot read bytes from file");
        }
    }
}
